local Archy = LibStub("AceAddon-3.0"):GetAddon("Archy")
local Config = Archy:NewModule("Config", "AceEvent-3.0")
local Artifact = Archy:GetModule("Artifact")
local L = LibStub("AceLocale-3.0"):GetLocale("Archy", false)
local LSM = Archy.lsm

local KeybindHelper = {}
do
	local t = {}
	function KeybindHelper:MakeKeyBindingTable(...)
		for k in pairs(t) do t[k] = nil end
		for i = 1, select("#", ...) do
			local key = select(i, ...)
			if key ~= "" then
				tinsert(t, key)
			end
		end
		return t
	end
end

local db
local imported = {}


--[[
	Keybinds
]]
BINDING_HEADER_ARCHY = L["Archy"]
BINDING_NAME_OPTIONS = L["BINDING_NAME_OPTIONS"]
BINDING_NAME_TOGGLE  = L["BINDING_NAME_TOGGLE"]
BINDING_NAME_SOLVE   = L["BINDING_NAME_SOLVE"]
BINDING_NAME_SOLVE_WITH_KEYSTONES   = L["BINDING_NAME_SOLVESTONE"]
BINDING_NAME_ARTIFACTS = L["BINDING_NAME_ARTIFACTS"]
BINDING_NAME_DIGSITES = L["BINDING_NAME_DIGSITES"]
_G["BINDING_NAME_SPELL Survey"] = L["Survey"]
--L["BINDING_NAME_SURVEY"]

-----------------------------------------------------------------------------
-- Register some media
if LSM then
LSM:Register("sound", "Rubber Ducky", [[Sound\Doodad\Goblin_Lottery_Open01.wav]])
LSM:Register("sound", "Cartoon FX", [[Sound\Doodad\Goblin_Lottery_Open03.wav]])
LSM:Register("sound", "Explosion", [[Sound\Doodad\Hellfire_Raid_FX_Explosion05.wav]])
LSM:Register("sound", "Shing!", [[Sound\Doodad\PortcullisActive_Closed.wav]])
LSM:Register("sound", "Wham!", [[Sound\Doodad\PVP_Lordaeron_Door_Open.wav]])
LSM:Register("sound", "Simon Chime", [[Sound\Doodad\SimonGame_LargeBlueTree.wav]])
LSM:Register("sound", "War Drums", [[Sound\Event Sounds\Event_wardrum_ogre.wav]])
LSM:Register("sound", "Cheer", [[Sound\Event Sounds\OgreEventCheerUnique.wav]])
LSM:Register("sound", "Humm", [[Sound\Spells\SimonGame_Visual_GameStart.wav]])
LSM:Register("sound", "Short Circuit", [[Sound\Spells\SimonGame_Visual_BadPress.wav]])
LSM:Register("sound", "Fel Portal", [[Sound\Spells\Sunwell_Fel_PortalStand.wav]])
LSM:Register("sound", "Fel Nova", [[Sound\Spells\SeepingGaseous_Fel_Nova.wav]])
LSM:Register("sound", "You Will Die!", [[Sound\Creature\CThun\CThunYouWillDIe.wav]])
LSM:Register("sound", "Archy: Ding Ding!", [[Interface\AddOns\Archy\Media\dingding.mp3]])
end

local nodeicon_options = {
	cyandot		= L["Light Blue Dot"],
	cross		= L["Cross"],
}

local outlines = {
	[""]             = L["None"],
	["OUTLINE"]      = L["Outline"],
	["THICKOUTLINE"] = L["Thick Outline"],
}

local function get(k)
	local ns, opt = string.split(".", k.arg)
	local val = db[ns][opt]
	if type(val) == "table" then
		return unpack(val)
	else
		return val
	end
end

local function set(k, v)
	local ns, opt = string.split(".", k.arg)
	db[ns][opt] = v
	
	Config:UpdateConfig()
end

local generalOptions = {
	type = "group",
	get = get,
	set = set,
	args = {
		desc = {
			order = 0,
			type = "description",
			name = L["Archy"],
		},
		show = {
			order = 1,
			name = L["Show Archy"],
			desc = L["Toggle the display of Archy"],
			type = "toggle",
			arg = "general.show",
		},
		reset = {
			order = 2,
			name = L["Reset Positions"],
			desc = L["Reset the window positions to defaults"],
			type = "execute",
			func = function()
				Config:ResetPositions()
			end,
		},
		lock = {
			order = 3,
			name = L["Lock Positions"],
			desc = L["Locks the windows so they cannot be repositioned by accident"],
			type = "toggle",
			arg = "general.lock",
			width = "double"
		},
		icon = {
			order = 4,
			name = L["Hide Minimap Button"],
			desc = L["Toggles the display of the Minimap Icon"],
			type = "toggle",
			arg = "general.icon.hide",
			get = function() return Archy.db.profile.general.icon.hide end,
			set = function(k, v) 
				Archy.db.profile.general.icon.hide = v; 
				if Archy.db.profile.general.icon.hide then
					Archy.icon:Hide("ArchyLDB")
				else
					Archy.icon:Show("ArchyLDB")
				end
			end,
			width = "double"
		},
		showRank = {
			order = 5,
			name = L["Show Archaeology Skill"],
			desc = L["Show your Archaeology skill on the Artifacts list header"],
			type = "toggle",
			arg = "general.showRank",
			width = "double",
		},	
	},
}

local surveyIndicatorOptions = {
	type = "group",
	get = get,
	set = set,
	args = {
		desc = {
			order = 0,
			type = "description",
			name = L["Control various aspects of Survey Distance Indicator options"],
		},
		enable = {
			order = 1,
			type = "toggle",
			name = L["Enable"],
			desc = L["Enable the Survey Distance Indicator"],
			width = "double",
			arg = "surveyIndicator.enable"
		},
		green = {
			order = 2,
			type = "range",
			name = L["Green Distance Radius"],
			desc = L["Set how large the green area of the survey distance indicator will use"],
			min = 1, max = 200, step = 1,
			arg = "surveyIndicator.greenDistance",
		},
		yellow = {
			order = 3,
			type = "range",
			name = L["Yellow Distance Radius"],
			desc = L["Set how large the yellow area of the survey distance indicator will use"],
			min = 1, max = 200, step = 1,
			arg = "surveyIndicator.yellowDistance",
		},
		scale = {
			order = 5,
			type = "range",
			name = L["Size"],
			desc = L["Set how large the Survey Distance Indicator is"],
			min = 0.25, max = 4, step = 0.01, bigStep = 0.05,
			arg = "surveyIndicator.scale",
		},
		alpha = {
			order = 6,
			type = "range",
			name = L["Opacity"],
			desc = L["Set how transparent or opaque the Survey Distance Indicator is"],
			min = 0.25, max = 1, step = 0.01, bigStep = 0.05,
			arg = "surveyIndicator.alpha",
		},
	},
}

local minimapOptions = {
	type = "group",
	get = get,
	set = set,
	args = {
		desc = {
			order = 0,
			type = "description",
			name = L["Control various aspects of Minimap options"],
		},
		show = {
			order = 1,
			type = "toggle",
			name = L["Show Dig Sites"],
			desc = L["Show your dig sites on the minimap"],
			arg = "minimap.show"
		},
		nearest = {
			order = 2,
			type = "toggle",
			name = L["Nearest only"],
			desc = L["Show only the nearest dig site on the minimap"],
			arg = "minimap.nearest",
			disabled = function() return not db.minimap.show end,
		},
		fragmentNodes = {
			order = 3,
			type = "toggle",
			name = L["Show Fragment Nodes"],
			desc = L["Show the locations where you have collected fragments"],
			arg = "minimap.fragmentNodes",
		},
		showMinerals = {
			order = 3.5,
			name = L["Node Icon"],
			desc = L["Icon to use for the fragment node icon"],
			type = "select",
			values = nodeicon_options,
			arg = "minimap.fragmentIcon",
		},
		blob = {
			order = 4,
			type = "toggle",
			name = L["Show Dig Site Boundaries on minimap"],
			desc = L["Show the dig site boundaries on the minimap"],
			width = "double",
			arg = "minimap.blob",
		},
		battlemapBlob = {
			order = 5,
			type = "toggle",
			name = L["Show Dig Site Boundaries on battlefield map"],
			desc = L["Show the dig site boundaries on the battlefield map"],
			width = "double",
			arg = "minimap.battlemapBlob",
		},
		blobAlpha = {
			order = 6,
			type = "range",
			name = L["Opacity"],
			desc = L["Set how transparent or opaque the Dig Site boundaries are"],
			min = 0.25, max = 1, step = 0.01, bigStep = 0.05,
			arg = "minimap.blobAlpha",
		},
	},
}

local digsiteOptions = {
	type = "group",
	childGroups = "tab",
	get = get,
	set = set,
	args = {
		options = {
			name = L["General"],
			order = 0,
			type = "group",
			get = get,
			set = set,
			args = {
				desc = {
					order = 0,
					type = "description",
					name = L["Control various aspects of the Dig Site options"],
				},
				show = {
					order = 1,
					type = "toggle",
					name = L["Show"],
					desc = L["Toggles the display of the Dig Sites list"],
					arg = "digsites.show",
					width = "double",
				},
				sortByDistance = {
					order = 2,
					type = "toggle",
					name = L["Sort by distance"],
					desc = L["Sort the dig sites by your distance to them"],
					arg = "digsites.sortByDistance",
				},
				showDistance = {
					order = 3,
					type = "toggle",
					name = L["Show Distances"],
					desc = L["Toggle the display of the distance to the dig sites"],
					arg = "digsites.showDistance",
				},
				showCounter = {
					order = 4,
					type = "toggle",
					name = L["Dig Counter"],
					desc = L["Toggle the display of the dig counter"],
					arg = "digsites.showCounter",
					width = "double",
				},
				showZone = {
					order = 5,
					type = "toggle",
					name = L["Show Zone"],
					desc = L["Toggle the display of the zone name"],
					arg = "digsites.showZone",
					width = "double",
				},
				scale = {
					order = 7,
					type = "range",
					name = L["Size"],
					desc = L["Set how large the Dig Site list is"],
					min = 0.25, max = 4, step = 0.01, bigStep = 0.05,
					arg = "digsites.scale",
				},
				alpha = {
					order = 8,
					type = "range",
					name = L["Opacity"],
					desc = L["Set how transparent or opaque the Dig Site list is"],
					min = 0.25, max = 1, step = 0.01, bigStep = 0.05,
					arg = "digsites.alpha",
				},
				backgroundColor = {
					order = 11,
					name = L["Background Color"],
					desc = L["Set the color of the Dig Sites list background"],
					type = "color",
					hasAlpha = true,
					arg = "digsites.backgroundColor",
					get = function(info)
						return db.digsites.backgroundColor.Red, db.digsites.backgroundColor.Green, db.digsites.backgroundColor.Blue, db.digsites.backgroundColor.Alpha
					end,
					set = function(info, r, g, b, a)
						db.digsites.backgroundColor.Red = r
						db.digsites.backgroundColor.Green = g
						db.digsites.backgroundColor.Blue = b
						db.digsites.backgroundColor.Alpha = a
						Config:UpdateColor()
					end,
				},
				headerBackgroundColor = {
					order = 12,
					name = L["Header Background Color"],
					desc = L["Set the color of the Dig Sites list header background"],
					type = "color",
					hasAlpha = true,
					arg = "digsites.headerBackgroundColor",
					get = function(info)
						return db.digsites.headerBackgroundColor.Red, db.digsites.headerBackgroundColor.Green, db.digsites.headerBackgroundColor.Blue, db.digsites.headerBackgroundColor.Alpha
					end,
					set = function(info, r, g, b, a)
						db.digsites.headerBackgroundColor.Red = r
						db.digsites.headerBackgroundColor.Green = g
						db.digsites.headerBackgroundColor.Blue = b
						db.digsites.headerBackgroundColor.Alpha = a
						Config:UpdateColor()
					end,
				},
			},
		},
		headerSettings = {
			type = "group",
			order = 2,
			name = L["Header Settings"],
			desc = L["Header Settings"],
			get = function(k)
				local ns, ns2, opt = string.split(".", k.arg)
				local val = db[ns][ns2][opt]
				if type(val) == "table" then
					return unpack(val)
				else
					return val
				end
			end,
			set = function(k, v)
				local ns, ns2, opt = string.split(".", k.arg)
				db[ns][ns2][opt] = v
				Config:UpdateConfig()
			end,
			args = {
				intro = {
					order = 0,
					type = "description",
					name = L["Configure header bar settings"],
				},
				height = {
					order = 1,
					type = "range",
					name = L["Header Bar Height"],
					desc = L["Height of the header bar"],
					min = 2, max = 32, step = 1,
					arg = "digsites.headerMedia.height",
				},
				font = {
					order = 2,
					type = "select",
					dialogControl = 'LSM30_Font',
					name = L["Font"],
					desc = L["The font that the header text will use"],
					values = AceGUIWidgetLSMlists.font,
					arg = "digsites.headerMedia.font",
				},
				fontOutline = {
					order = 4,
					type = "select",
					name = L["Font Outline"],
					desc = L["The outline that the header text will use"],
					values = outlines,
					arg = "digsites.headerMedia.fontOutline",
				},
				fontColor = {
					type = "color",
					order = 5,
					name = L["Font Color"],
					desc = L["The color of the header text"],
					hasAlpha = true,
					get = function(info)
						return db.digsites.headerMedia.fontColor.Red, db.digsites.headerMedia.fontColor.Green, db.digsites.headerMedia.fontColor.Blue, db.digsites.headerMedia.fontColor.Alpha
					end,
					set = function(info, r, g, b, a)
						db.digsites.headerMedia.fontColor.Red = r
						db.digsites.headerMedia.fontColor.Green = g
						db.digsites.headerMedia.fontColor.Blue = b
						db.digsites.headerMedia.fontColor.Alpha = a
						Config:UpdateColor()
					end,
				},
				fontSize = {
					type = "range",
					order = 3,
					name = L["Font Size"],
					desc = L["Control the font size of the header text"],
					min = 4, max = 30, step = 1,
					arg = "digsites.headerMedia.fontSize",
				},
			},
		},
		rowSettings = {
			type = "group",
			order = 2,
			name = L["Row Settings"],
			desc = L["Row Settings"],
			get = function(k)
				local ns, ns2, opt = string.split(".", k.arg)
				local val = db[ns][ns2][opt]
				if type(val) == "table" then
					return unpack(val)
				else
					return val
				end
			end,
			set = function(k, v)
				local ns, ns2, opt = string.split(".", k.arg)
				db[ns][ns2][opt] = v
				Config:UpdateConfig()
			end,
			args = {
				intro = {
					order = 0,
					type = "description",
					name = L["Configure dig site row settings"],
				},
				height = {
					order = 1,
					type = "range",
					name = L["Dig Site Row Height"],
					desc = L["Height of the dig site row"],
					min = 2, max = 32, step = 1,
					arg = "digsites.rowMedia.height",
				},
				font = {
					order = 2,
					type = "select",
					dialogControl = 'LSM30_Font',
					name = L["Font"],
					desc = L["The font that the dig site text will use"],
					values = AceGUIWidgetLSMlists.font,
					arg = "digsites.rowMedia.font",
				},
				fontOutline = {
					order = 3.5,
					type = "select",
					name = L["Font Outline"],
					desc = L["The outline that the dig site text will use"],
					values = outlines,
					arg = "digsites.rowMedia.fontOutline",
				},
				fontColor = {
					type = "color",
					order = 4,
					name = L["Font Color"],
					desc = L["The color of the dig site text"],
					hasAlpha = true,
					get = function(info)
						return db.digsites.rowMedia.fontColor.Red, db.digsites.rowMedia.fontColor.Green, db.digsites.rowMedia.fontColor.Blue, db.digsites.rowMedia.fontColor.Alpha
					end,
					set = function(info, r, g, b, a)
						db.digsites.rowMedia.fontColor.Red = r
						db.digsites.rowMedia.fontColor.Green = g
						db.digsites.rowMedia.fontColor.Blue = b
						db.digsites.rowMedia.fontColor.Alpha = a
						Config:UpdateColor()
					end,
				},
				fontSize = {
					type = "range",
					order = 3,
					name = L["Font Size"],
					desc = L["Control the font size of the dig site text"],
					min = 4, max = 30, step = 1,
					arg = "digsites.rowMedia.fontSize",
				},
			},
		},

	},
}

local artifactOptions = {
	type = "group",
	childGroups = "tab",
	args = {
		options = {
			name = L["General"],
			order = 0,
			type = "group",
			get = get,
			set = set,
			args = {
				desc = {
					order = 0,
					type = "description",
					name = L["Control various aspects of the Artifact options"],
				},
				show = {
					order = 1,
					type = "toggle",
					name = L["Show"],
					desc = L["Toggles the display of the Artifacts list"],
					arg = "artifacts.show",
				},
				filter = {
					order = 2,
					type = "toggle",
					name = L["Filter by Continent"],
					desc = L["Filter the Artifact list by races on the continent"],
					arg = "artifacts.filter",
					disabled = function() return not db.artifacts.show end,
				},
				announce = {
					order = 3,
					type = "toggle",
					name = L["Announce when solvable"],
					desc = L["Announce in the chat window when an artifact can be solved with fragments"],
					arg = "artifacts.announce",
				},
				keystoneAnnounce = {
					order = 4,
					type = "toggle",
					name = L["Include key stones"],
					desc = L["Announce in the chat window when an artifact can be solved with fragments and key stones"],
					arg = "artifacts.keystoneAnnounce",
					disabled = function() return not db.artifacts.announce end,
				},
				ping = {
					order = 5,
					type = "toggle",
					name = L["Play sound when solvable"],
					desc = L["Play a sound when an artifact can be solved with fragments"],
					arg = "artifacts.ping",
				},
				keystonePing = {
					order = 6,
					type = "toggle",
					name = L["Include key stones"],
					desc = L["Play a sound when an artifact can be solved with fragments and key stones"],
					arg = "artifacts.keystonePing",
					disabled = function() return not db.artifacts.ping end,
				},
				confirmSolve = {
					order = 6.5,
					type = "toggle",
					name = L["Confirm solves near skill cap"],
					desc = L["Ask for confirmation when your skill nears the cap.  When enabled, no confirmation is needed for Illustrious Archaeologists."],
					arg = "artifacts.confirmSolve",
					width = "double",
				},
				scale = {
					order = 7,
					type = "range",
					name = L["Size"],
					desc = L["Set how large the Artifacts list is"],
					min = 0.25, max = 4, step = 0.01, bigStep = 0.05,
					arg = "artifacts.scale",
				},
				alpha = {
					order = 8,
					type = "range",
					name = L["Opacity"],
					desc = L["Set how transparent or opaque the Artifacts list is"],
					min = 0.25, max = 1, step = 0.01, bigStep = 0.05,
					arg = "artifacts.alpha",
				},
				backgroundColor = {
					order = 11,
					name = L["Background Color"],
					desc = L["Set the color of the Artifacts list background"],
					type = "color",
					hasAlpha = true,
					arg = "artifacts.backgroundColor",
					get = function(info)
						return db.artifacts.backgroundColor.Red, db.artifacts.backgroundColor.Green, db.artifacts.backgroundColor.Blue, db.artifacts.backgroundColor.Alpha
					end,
					set = function(info, r, g, b, a)
						db.artifacts.backgroundColor.Red = r
						db.artifacts.backgroundColor.Green = g
						db.artifacts.backgroundColor.Blue = b
						db.artifacts.backgroundColor.Alpha = a
						Config:UpdateColor()
					end,
				},
				headerBackgroundColor = {
					order = 12,
					name = L["Header Background Color"],
					desc = L["Set the color of the Artifacts list header background"],
					type = "color",
					hasAlpha = true,
					arg = "artifacts.headerBackgroundColor",
					get = function(info)
						return db.artifacts.headerBackgroundColor.Red, db.artifacts.headerBackgroundColor.Green, db.artifacts.headerBackgroundColor.Blue, db.artifacts.headerBackgroundColor.Alpha
					end,
					set = function(info, r, g, b, a)
						db.artifacts.headerBackgroundColor.Red = r
						db.artifacts.headerBackgroundColor.Green = g
						db.artifacts.headerBackgroundColor.Blue = b
						db.artifacts.headerBackgroundColor.Alpha = a
						Config:UpdateColor()
					end,
				},
			},				
		},
		blacklist = {
			order = 1,
			type = "group",
			name = L["Blacklist"],
			args = {
				desc = {
					order = 0,
					type = "description",
					name = L["Allows you to blacklist races from being used by Archy"],
				},
				raceList = {
					order = 1,
					type = "select", 
					name = L["Races"],
					desc = L["Select a race to blacklist"],
					values = function() return Config:GetBlacklistableRaces() end,
					get = function() return selectedArtifactRace end,
					set = function(k, v) selectedArtifactRace = v end,
					width = "double",
				},
				add = {
					order = 2,
					name = L["Blacklist"],
					desc = L["Blacklist selected race from artifact use"],
					type = "execute",
					width = "double",
					func = function()
						if selectedArtifactRace then
							Config:BlacklistRace(selectedArtifactRace)
							selectedArtifactRace = nil
							Config:UpdateConfig()
						end
					end,
					disabled = function()
						return selectedArtifactRace == nil
					end,
				},
				blacklist = {
					order = 3,
					name = L["Blacklisted Races"],
					desc = L["List of blacklisted races"],
					type = "select",
					width = "double",
					values = function() return Config:GetBlacklistedRaces() end,
					get = function() return selectedBlacklistRace end,
					set = function(k,v) selectedBlacklistRace = v end,					
				},
				delete = {
					order = 4,
					name = L["Remove from blacklist"],
					desc = L["Remove selected race from the blacklist"],
					type = "execute",
					width = "double",
					func = function()
						if selectedBlacklistRace then
							Config:WhitelistRace(selectedBlacklistRace)
							selectedBlacklistRace = nil
							Config:UpdateConfig()
						end
					end,
					disabled = function()
						return selectedBlacklistRace == nil
					end,
				},
			},
		},
		headerSettings = {
			type = "group",
			order = 2,
			name = L["Header Settings"],
			desc = L["Header Settings"],
			get = function(k)
				local ns, ns2, opt = string.split(".", k.arg)
				local val = db[ns][ns2][opt]
				if type(val) == "table" then
					return unpack(val)
				else
					return val
				end
			end,
			set = function(k, v)
				local ns, ns2, opt = string.split(".", k.arg)
				db[ns][ns2][opt] = v
				Config:UpdateConfig()
			end,
			args = {
				intro = {
					order = 0,
					type = "description",
					name = L["Configure header bar settings"],
				},
				height = {
					order = 1,
					type = "range",
					name = L["Header Bar Height"],
					desc = L["Height of the header bar"],
					min = 2, max = 32, step = 1,
					arg = "artifacts.headerMedia.height",
				},
				font = {
					order = 2,
					type = "select",
					dialogControl = 'LSM30_Font',
					name = L["Font"],
					desc = L["The font that the header text will use"],
					values = AceGUIWidgetLSMlists.font,
					arg = "artifacts.headerMedia.font",
				},
				fontOutline = {
					order = 4,
					type = "select",
					name = L["Font Outline"],
					desc = L["The outline that the header text will use"],
					values = outlines,
					arg = "artifacts.headerMedia.fontOutline",
				},
				fontColor = {
					type = "color",
					order = 5,
					name = L["Font Color"],
					desc = L["The color of the header text"],
					hasAlpha = true,
					get = function(info)
						return db.artifacts.headerMedia.fontColor.Red, db.artifacts.headerMedia.fontColor.Green, db.artifacts.headerMedia.fontColor.Blue, db.artifacts.headerMedia.fontColor.Alpha
					end,
					set = function(info, r, g, b, a)
						db.artifacts.headerMedia.fontColor.Red = r
						db.artifacts.headerMedia.fontColor.Green = g
						db.artifacts.headerMedia.fontColor.Blue = b
						db.artifacts.headerMedia.fontColor.Alpha = a
						Config:UpdateColor()
					end,
				},
				fontSize = {
					type = "range",
					order = 3,
					name = L["Font Size"],
					desc = L["Control the font size of the header text"],
					min = 4, max = 30, step = 1,
					arg = "artifacts.headerMedia.fontSize",
				},
			},
		},
		rowSettings = {
			type = "group",
			order = 2,
			name = L["Row Settings"],
			desc = L["Row Settings"],
			get = function(k)
				local ns, ns2, opt = string.split(".", k.arg)
				local val = db[ns][ns2][opt]
				if type(val) == "table" then
					return unpack(val)
				else
					return val
				end
			end,
			set = function(k, v)
				local ns, ns2, opt = string.split(".", k.arg)
				db[ns][ns2][opt] = v
				Config:UpdateConfig()
			end,
			args = {
				intro = {
					order = 0,
					type = "description",
					name = L["Configure artifact row settings"],
				},
				height = {
					order = 1,
					type = "range",
					name = L["Artifact Row Height"],
					desc = L["Height of the artifact row"],
					min = 2, max = 32, step = 1,
					arg = "artifacts.rowMedia.height",
				},
				font = {
					order = 2,
					type = "select",
					dialogControl = 'LSM30_Font',
					name = L["Font"],
					desc = L["The font that the artifact text will use"],
					values = AceGUIWidgetLSMlists.font,
					arg = "artifacts.rowMedia.font",
				},
				fontOutline = {
					order = 3.5,
					type = "select",
					name = L["Font Outline"],
					desc = L["The outline that the artifact text will use"],
					values = outlines,
					arg = "artifacts.rowMedia.fontOutline",
				},
				fontColor = {
					type = "color",
					order = 4,
					name = L["Font Color"],
					desc = L["The color of the artifact text"],
					hasAlpha = true,
					get = function(info)
						return db.artifacts.rowMedia.fontColor.Red, db.artifacts.rowMedia.fontColor.Green, db.artifacts.rowMedia.fontColor.Blue, db.artifacts.rowMedia.fontColor.Alpha
					end,
					set = function(info, r, g, b, a)
						db.artifacts.rowMedia.fontColor.Red = r
						db.artifacts.rowMedia.fontColor.Green = g
						db.artifacts.rowMedia.fontColor.Blue = b
						db.artifacts.rowMedia.fontColor.Alpha = a
						Config:UpdateColor()
					end,
				},
				keystoneFontColor = {
					type = "color",
					order = 4,
					name = L["Key Stone Font Color"],
					desc = L["The color of the key stone text"],
					hasAlpha = true,
					get = function(info)
						return db.artifacts.rowMedia.keystoneFontColor.Red, db.artifacts.rowMedia.keystoneFontColor.Green, db.artifacts.rowMedia.keystoneFontColor.Blue, db.artifacts.rowMedia.keystoneFontColor.Alpha
					end,
					set = function(info, r, g, b, a)
						db.artifacts.rowMedia.keystoneFontColor.Red = r
						db.artifacts.rowMedia.keystoneFontColor.Green = g
						db.artifacts.rowMedia.keystoneFontColor.Blue = b
						db.artifacts.rowMedia.keystoneFontColor.Alpha = a
						Config:UpdateColor()
					end,
				},
				rareFontColor = {
					type = "color",
					order = 6,
					name = L["Rare Artifact Font Color"],
					desc = L["The color of the rare artifact text"],
					hasAlpha = true,
					get = function(info)
						return db.artifacts.rowMedia.rareFontColor.Red, db.artifacts.rowMedia.rareFontColor.Green, db.artifacts.rowMedia.rareFontColor.Blue, db.artifacts.rowMedia.rareFontColor.Alpha
					end,
					set = function(info, r, g, b, a)
						db.artifacts.rowMedia.rareFontColor.Red = r
						db.artifacts.rowMedia.rareFontColor.Green = g
						db.artifacts.rowMedia.rareFontColor.Blue = b
						db.artifacts.rowMedia.rareFontColor.Alpha = a
						Config:UpdateColor()
					end,
				},
				grayFontColor = {
					type = "color",
					order = 5,
					name = L["Common Artifact Font Color"],
					desc = L["The color of the common artifact text"],
					hasAlpha = true,
					get = function(info)
						return db.artifacts.rowMedia.grayFontColor.Red, db.artifacts.rowMedia.grayFontColor.Green, db.artifacts.rowMedia.grayFontColor.Blue, db.artifacts.rowMedia.grayFontColor.Alpha
					end,
					set = function(info, r, g, b, a)
						db.artifacts.rowMedia.grayFontColor.Red = r
						db.artifacts.rowMedia.grayFontColor.Green = g
						db.artifacts.rowMedia.grayFontColor.Blue = b
						db.artifacts.rowMedia.grayFontColor.Alpha = a
						Config:UpdateColor()
					end,
				},
				fontSize = {
					type = "range",
					order = 3,
					name = L["Font Size"],
					desc = L["Control the font size of the artifact text"],
					min = 4, max = 30, step = 1,
					arg = "artifacts.rowMedia.fontSize",
				},
			},
		},

	},
}

local selectedArtifactRace, selectedBlacklistRace

function Config:GetBlacklistedRaces()
	local numRaces = GetNumArchaeologyRaces()
	local races = {}
	for i = 1, numRaces do
		local name, _, _, _ = GetArchaeologyRaceInfo(i)
		if tContains(db.artifacts.blacklist, i) then
			races[i] = name
		end
	end
	return races
end

function Config:GetBlacklistableRaces()
	local numRaces = GetNumArchaeologyRaces()
	local races = {}
	for i = 1, numRaces do
		local name, _, _, _ = GetArchaeologyRaceInfo(i)
		if not tContains(db.artifacts.blacklist, i) then
			races[i] = name
		end
	end
	return races
end

function Config:BlacklistRace(race)
	if not tContains(db.artifacts.blacklist, race) then
		tinsert(db.artifacts.blacklist, race)
	end
end

function Config:WhitelistRace(race)
	if tContains(db.artifacts.blacklist, race) then
		local raceIndex
		table.foreach(db.artifacts.blacklist, function(k,v) if v == race then raceIndex = k end end)
		if raceIndex then
			tremove(db.artifacts.blacklist, raceIndex)
		end
	end	
end


local tomtomOptions = {
	type = "group",
	get = get,
	set = set,
	args = {
		desc = {
			order = 0,
			type = "description",
			name = L["Control various aspects of TomTom integration"],
		},
		enable = {
			order = 1,
			type = "toggle",
			name = L["Enable TomTom integration"],
			desc = L["Toggle if Archy will send the nearest dig site waypoint information to TomTom"],
			arg = "tomtom.enable",
			width = "double"
		},
		arrivalDistance = {
			order = 2,
			type = "range",
			name = L["\"Arrival Distance\""],
			desc = L["This setting will control the distance at which the waypoint arrow switches to a downwards arrow, indicating you have arrived at your destination.\nNOTE: This may not work with emulation addons if they do not support this."],
			cmdHidden = true,
			min = 0, max = 150, step = 5,
			arg = "tomtom.arrivalDistance",
			disabled = function() return not db.tomtom.enable or not TomTom end,
			width = "double"
		},
		arrivalPing = {
			order = 3,
			type = "toggle",
			name = L["Play a sound when arriving at a waypoint"],
			desc = L["When you 'arrive' at a waypoint (this distance is controlled by the 'Arrival Distance' setting in this group) a sound can be played to indicate this.  You can enable or disable this sound using this setting."],
			width = "double",
			cmdHidden = true,
			arg = "tomtom.arrivalPing",
			disabled = function() return not db.tomtom.enable or not TomTom  end,
			width = "double"
		},
	},
}

local ldbOptions = {
	type = "group",
	get = get,
	set = set,
	args = {
		desc = {
			order = 0,
			type = "description",
			name = L["Control various aspects of LDB tooltip"],
		},
		artifacts = {
			order = 1,
			type = "toggle",
			name = L["Show Artifacts"],
			desc = L["Toggle if Artifacts will be shown"],
			cmdHidden = true,
			arg = "ldb.artifacts",
			width = "double"
		},
		digsites = {
			order = 2,
			type = "toggle",
			name = L["Show Dig Sites"],
			desc = L["Toggle if Dig Sites will be shown"],
			cmdHidden = true,
			arg = "ldb.digsites",
		},
		filterDigsites = {
			order = 3,
			type = "toggle",
			name = L["Filter Dig Sites"],
			desc = L["Toggle if only the current continent's dig sites will be shown"],
			cmdHidden = true,
			arg = "ldb.filterDigsites",
			disabled = function() return not db.ldb.digsites end,
		},
	
	}
}


--[[
	Initialize the config system
]]
local acr = LibStub("AceConfigRegistry-3.0")
local acd = LibStub("AceConfigDialog-3.0")

local function findPanel(name, parent)
	for i, button in next, InterfaceOptionsFrameAddOns.buttons do
		if button.element then
			if name and button.element.name == name then return button
			elseif parent and button.element.parent == parent then return button
			end
		end
	end
end

function Config:OnInitialize()
	db = Archy.db.profile
	
	acr:RegisterOptionsTable("Archy", generalOptions, { "/archy" } )
	Archy.options = acd:AddToBlizOptions("Archy", "Archy")
	Archy.options:HookScript("OnShow", function()
		local p = findPanel("Archy")
		if p and p.element.collapsed then OptionsListButtonToggle_OnClick(p.toggle) end
	end)
	
	Config:RegisterModule("Minimap", L["Minimap"], minimapOptions)
	Config:RegisterModule("Dig Sites", L["Dig Sites"], digsiteOptions)
	Config:RegisterModule("Artifacts", L["Artifacts"], artifactOptions)
	Config:RegisterModule("Survey Distance Indicator", L["Survey Distance Indicator"], surveyIndicatorOptions)
	Config:RegisterModule("Navigation", L["Navigation"], tomtomOptions)
	Config:RegisterModule("LDB", L["LDB"], ldbOptions)

	acr:RegisterOptionsTable("Archy/Profiles", LibStub("AceDBOptions-3.0"):GetOptionsTable(Archy.db))
	acd:AddToBlizOptions("Archy/Profiles", "Profiles", "Archy")

	
	local function dump_table(t)
		for key,value in pairs(t) do
			if type(value) == "table" then
				print("start of " .. key .. " table")
				dump_table(value)
				print ("end of " .. key .. " table");
			elseif type(value) == "userdata" then
			else
				print(key .. '=' .. value or "nil")
			end
		end
	end

	local function handler(msg, editbox)
		if msg == L["config"] then
			Archy:OpenOptions()
		elseif msg == L["stealth"] then
			Config:SendMessage("ArchyStealthMode")
		elseif msg == L["dig sites"] then
			Archy.db.profile.digsites.show = not Archy.db.profile.digsites.show
			Config:UpdateConfig()
		elseif msg == L["artifacts"] then
			Archy.db.profile.artifacts.show = not Archy.db.profile.artifacts.show
			Config:UpdateConfig()
		elseif msg == L["solve"] then
			Archy:GetModule("Artifact"):SolveAnyArtifact(false)
		elseif msg == L["solve stone"] then
			Archy:GetModule("Artifact"):SolveAnyArtifact(true)
		elseif msg == L["nearest"] or msg == L["closest"] then
			Archy:GetModule("Digsite"):AnnounceNearest()
			-- Announce the nearest digsite
		elseif msg == L["reset"] then
			Config:ResetPositions()
		elseif msg == L["tomtom"] then
			Archy.db.profile.tomtom.enable = not Archy.db.profile.tomtom.enable
			Config:UpdateConfig()
		elseif msg == L["minimap"] then
			Archy.db.profile.minimap.show = not Archy.db.profile.minimap.show
			Config:UpdateConfig()
		else
			Archy:Print(L["Available commands are:"])
			Archy:Print("|cFF00FF00" .. L["config"] .. "|r - " .. L["Shows the Options"])
			Archy:Print("|cFF00FF00" .. L["stealth"] .. "|r - " .. L["Toggles the display of the Artifacts and Dig Sites lists"])
			Archy:Print("|cFF00FF00" .. L["dig sites"] .. "|r - " .. L["Toggles the display of the Dig Sites list"])
			Archy:Print("|cFF00FF00" .. L["artifacts"] .. "|r - " .. L["Toggles the display of the Artifacts list"])
			Archy:Print("|cFF00FF00" .. L["solve"] .. "|r - " .. L["Solves the first artifact it finds that it can solve"])
			Archy:Print("|cFF00FF00" .. L["solve stone"] .. "|r - " .. L["Solves the first artifact it finds that it can solve (including key stones)"])
			Archy:Print("|cFF00FF00" .. L["nearest"] .. "|r or |cFF00FF00" .. L["closest"] .. "|r - " .. L["Announces the nearest dig site to you"])
			Archy:Print("|cFF00FF00" .. L["reset"] .. "|r - " .. L["Reset the window positions to defaults"])
			Archy:Print("|cFF00FF00" .. L["tomtom"] .. "|r - " .. L["Toggles TomTom Integration"])
			Archy:Print("|cFF00FF00" .. L["minimap"] .. "|r - " .. L["Toggles the dig site icons on the minimap"])
			
		end
	end
	
	SLASH_Archy1 = "/archy"
	SlashCmdList.Archy = handler
	
	self:RegisterMessage("ArchyConfigChanged")
end

function Config:OnEnable()
	db = Archy.db.profile
end

function Config:UpdateConfig()
	self:SendMessage("ArchyConfigChanged")
--	Archy:ShowHideIcon()
end

function Config:UpdateColor()
	self:SendMessage("ArchyColorChanged")
end

function Config:ArchyConfigChanged()
	db = Archy.db.profile
end

function Config:RegisterModule(moduleName, name, optionsTable)
	acr:RegisterOptionsTable("Archy/" .. moduleName, optionsTable)
	acd:AddToBlizOptions("Archy/" .. moduleName, name, "Archy")
end

function Config:ResetPositions()
	db.digsites.location.x, db.digsites.location.y = 0, 0
	db.artifacts.location.x, db.artifacts.location.y = 0, 0
	db.surveyIndicator.location.x, db.surveyIndicator.location.y = 0, 0
	self:SendMessage("ArchyPositionReset")
end